package cn.com.cetccst.mdm.engine;

import android.app.Activity;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;

import com.huawei.android.app.admin.DeviceApplicationManager;
import com.huawei.android.app.admin.DeviceCameraManager;
import com.huawei.android.app.admin.DeviceControlManager;
import com.huawei.android.app.admin.DeviceHwSystemManager;
import com.huawei.android.app.admin.DevicePackageManager;
import com.huawei.android.app.admin.DeviceRestrictionManager;
import com.huawei.android.app.admin.DeviceSettingsManager;
import com.huawei.android.app.admin.DeviceTelephonyManager;
import com.huawei.android.app.admin.DeviceVpnManager;

import java.util.ArrayList;
import java.util.List;

import cn.com.cetccst.tools.log.CommonLogger;

public class HWMdmEngine extends BaseMDMEngine {

    private static final String TAG = "HwMdmEngine";
    private DeviceApplicationManager deviceApplicationManager;
    private DevicePackageManager devicePackageManager;
    private DeviceSettingsManager settingsManager;
    private DeviceRestrictionManager restrictionManager;
    private DeviceHwSystemManager systemManager;
    private DeviceCameraManager cameraManager;
    private DeviceVpnManager vpnManager;
    private DeviceTelephonyManager telephonyManager;
    private DeviceControlManager deviceControlManager;
    private DevicePolicyManager dpm;

    public HWMdmEngine(Context context) {
        super(context);
        deviceApplicationManager = new DeviceApplicationManager();
        settingsManager = new DeviceSettingsManager();
        restrictionManager = new DeviceRestrictionManager();
        cameraManager = new DeviceCameraManager();
        vpnManager = new DeviceVpnManager();
        devicePackageManager = new DevicePackageManager();
        telephonyManager = new DeviceTelephonyManager();
        deviceControlManager = new DeviceControlManager();
        dpm = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
    }

    @Override
    public boolean isActiveDeviceAdmin() {
        return devicePolicyManager.isAdminActive(adminComponent);
    }

    @Override
    public boolean setActiveDeviceAdmin(Activity activity) {
        return deviceControlManager.setForcedActiveDeviceAdmin(adminComponent, context);
    }

    @Override
    public void controlBluetooth(boolean disabled) {
        restrictionManager.setBluetoothDisabled(adminComponent, disabled);
    }

    @Override
    public boolean isBluetoothControlled() {
        return restrictionManager.isBluetoothDisabled(adminComponent);
    }

    @Override
    public void controlCamera(boolean disabled) {
        dpm.setCameraDisabled(adminComponent, disabled);
    }

    @Override
    public boolean isCameraControlled() {
        return dpm.getCameraDisabled(adminComponent);
    }

    @Override
    public void controlWifi(boolean disabled) {
        restrictionManager.setWifiDisabled(adminComponent, disabled);
    }

    @Override
    public boolean isWifiControlled() {
        return restrictionManager.isWifiDisabled(adminComponent);
    }

    @Override
    public void controlMicroPhone(boolean disabled) {
        restrictionManager.setMicrophoneDisabled(adminComponent, disabled);
    }

    @Override
    public boolean isMicroPhoneControlled() {
        return restrictionManager.isMicrophoneDisabled(adminComponent);
    }

    @Override
    public void controlExternalStorage(boolean disabled) {
        restrictionManager.setExternalStorageDisabled(adminComponent, disabled);
    }

    @Override
    public boolean isExternalStorageControlled() {
        return restrictionManager.isExternalStorageDisabled(adminComponent);
    }

    @Override
    public void controlScreenShot(boolean disabled) {
        restrictionManager.setScreenCaptureDisabled(adminComponent, disabled);
    }

    @Override
    public boolean isScreenShotControlled() {
        return restrictionManager.isScreenCaptureDisabled(adminComponent);
    }

    @Override
    public void controlNFC(boolean disabled) {
        restrictionManager.setNFCDisabled(adminComponent, disabled);
    }

    @Override
    public boolean isNFCControlled() {
        return restrictionManager.isNFCDisabled(adminComponent);
    }

    @Override
    public void controlMobileHotSpot(boolean disabled) {
        restrictionManager.setWifiApDisabled(adminComponent, disabled);
    }

    @Override
    public boolean isMobileHotSpotControlled() {
        return restrictionManager.isWifiApDisabled(adminComponent);
    }

    @Override
    public void controlCallout(boolean disabled) {
        restrictionManager.setVoiceDisabled(adminComponent, disabled);
    }

    @Override
    public boolean isCalloutControlled() {
        return restrictionManager.isVoiceDisabled(adminComponent);
    }

    @Override
    public void controlSms(boolean disabled) {
        restrictionManager.setSMSDisabled(adminComponent, disabled);
    }

    @Override
    public boolean isSmsControlled() {
        return restrictionManager.isSMSDisabled(adminComponent);
    }

    @Override
    public void controlMobileData(boolean disabled) {
        restrictionManager.setDataConnectivityDisabled(adminComponent, disabled);
        telephonyManager.setSlot2DataConnectivityDisabled(adminComponent, disabled);

    }

    @Override
    public boolean isMobileDataControlled() {
        return restrictionManager.isDataConnectivityDisabled(adminComponent) && telephonyManager.isSlot2DataConnectivityDisabled(adminComponent);
    }

    @Override
    public void controlVolumeDown(boolean disabled) {
        restrictionManager.setVolumeAdjustDisabled(adminComponent, disabled);
    }

    @Override
    public boolean isVolumeDownControlled() {
        return restrictionManager.isVolumeAdjustDisabled(adminComponent);
    }

    @Override
    public void controlAutoTime(boolean disabled) {
        settingsManager.setTimeAndDateSetDisabled(adminComponent, !disabled);
    }

    @Override
    public boolean isAutoTimeControlled() {
        return settingsManager.isTimeAndDateSetDisabled(adminComponent);
    }

    @Override
    public void controlUsbData(boolean disabled) {
        restrictionManager.setUSBDataDisabled(adminComponent, disabled);
    }

    @Override
    public boolean isUsbDataControlled() {
        return restrictionManager.isUSBDataDisabled(adminComponent);
    }

    @Override
    public void controlUsbDebug(boolean disabled) {
        restrictionManager.setAdbDisabled(adminComponent, disabled);
    }

    @Override
    public boolean isUsbDebugControlled() {
        return restrictionManager.isAdbDisabled(adminComponent);
    }

    @Override
    public void controlRestoreFactory(boolean disabled) {
        settingsManager.setRestoreFactoryDisabled(adminComponent, disabled);
    }

    @Override
    public boolean isRestoreFactoryControlled() {
        return settingsManager.isRestoreFactoryDisabled(adminComponent);
    }

    @Override
    public void controlSystemUpgrade(boolean disabled) {
        restrictionManager.setSystemUpdateDisabled(adminComponent, disabled);
    }

    @Override
    public boolean isSystemUpgradeControlled() {
        return restrictionManager.isSystemUpdateDisabled(adminComponent);
    }

    @Override
    public void controlGPS(boolean disabled) {

    }

    @Override
    public boolean setDisallowRunningApps(List<String> packageNames, boolean isBlock) {
        List<String> pendingList = new ArrayList<>();
        if (packageNames != null) {
            List<String> blockedList = deviceApplicationManager.getDisallowedRunningApp(adminComponent);
            if (blockedList == null || blockedList.isEmpty()) {
                pendingList.addAll(packageNames);
            } else {
                for (String source : packageNames) {
                    PackageInfo packageInfo = null;
                    try {
                        packageInfo = packageManager.getPackageInfo(source, PackageManager.GET_UNINSTALLED_PACKAGES);
                    } catch (PackageManager.NameNotFoundException e) {
                        //
                    }
                    if (packageInfo == null) {
                        continue;
                    }
                    if (isBlock) {
                        if (!blockedList.contains(source)) {
                            pendingList.add(source);
                        }
                    } else {
                        if (blockedList.contains(source)) {
                            pendingList.add(source);
                        }
                    }
                }
            }

            if (isBlock) {
                if (!pendingList.isEmpty()) {
                    deviceApplicationManager.addDisallowedRunningApp(adminComponent, pendingList);
                    CommonLogger.info("set packages to be disabled via HW with size " + pendingList.size());
                }
            } else {
                if (!pendingList.isEmpty()) {
                    deviceApplicationManager.removeDisallowedRunningApp(adminComponent, pendingList);
                    CommonLogger.info("set packages to be enable via HW with size " + pendingList.size());
                }
            }
        }
        return true;
    }

    @Override
    public List<String> getDisallowRunningApps() {
        return deviceApplicationManager.getDisallowedRunningApp(adminComponent);
    }

    @Override
    public void installPackage(String apkPath) {
        String packageName = parsePackageName(apkPath);
        try {
            devicePackageManager.installPackage(adminComponent, apkPath);
        } catch (Exception e) {
            CommonLogger.error("Silent install failed with hw API : " + packageName, e);
        }

        CommonLogger.info("install app via hw :" + packageName);
    }

    @Override
    public void uninstallPackage(String packageName) {
        try {
            devicePackageManager.uninstallPackage(adminComponent, packageName, false);
        } catch (Exception e) {
            CommonLogger.error("uninstall failed with hw API : " + packageName, e);

        }
        CommonLogger.info("uninstall done with via hw .");
    }

    @Override
    public void formatSDCard() {
        deviceControlManager.formatSDCard(adminComponent, "0");
    }

    @Override
    public void factoryReset() {
        super.factoryReset();
    }

    @Override
    public void shutdown() {
        if (dpm.isAdminActive(adminComponent)) {
            deviceControlManager.shutdownDevice(adminComponent);
            CommonLogger.info("shutdown device completely.");
        } else {
            CommonLogger.info("shutdown device faile because of no  admin. .");
        }
    }

    @Override
    public void reboot() {
        if (dpm.isAdminActive(adminComponent)) {
            deviceControlManager.rebootDevice(adminComponent);
            CommonLogger.info("restart device completely. .");
        } else {
            CommonLogger.info("restart device faile because of no  admin. .");
        }
    }

    @Override
    public boolean setInstallSourceApps(List<String> packageNames) {
        return false;
    }

    @Override
    public List<String> getInstallSourceApps() {
        return null;
    }

    @Override
    public boolean setNetworkWhiteListApps(List<String> packageNames) {
        return false;
    }

    @Override
    public List<String> getNetworkWhiteListApps() {
        return null;
    }

    @Override
    public boolean setKeepLiveApps(List<String> packageNames) {
        deviceApplicationManager.addPersistentApp(adminComponent, packageNames);
        return true;
    }

    @Override
    public List<String> getKeepLiveApps() {
        return deviceApplicationManager.getPersistentApp(adminComponent);
    }

    @Override
    public boolean setSuperApps(List<String> packageNames) {
        return false;
    }

    @Override
    public List<String> getSuperApps() {
        return null;
    }

    @Override
    public boolean setDevicePassword(String password) {
        return super.setDevicePassword(password);
    }

    @Override
    public String getName() {
        return "hw";
    }

    @Override
    public void controlSingleApp(boolean disabled) {
        try {
            restrictionManager.setHomeButtonDisabled(adminComponent, disabled);
            restrictionManager.setTaskButtonDisabled(adminComponent, disabled);
            restrictionManager.setBackButtonDisabled(adminComponent, disabled);
            restrictionManager.setStatusBarDisabled(adminComponent, disabled);
            //restrictionManager.setStatusBarExpandPanelDisabled(adminComponent, disabled);
            restrictionManager.setSendNotificationDisabled(adminComponent, disabled);
            //restrictionManager.setSettingsApplicationDisabled(adminComponent, disabled);
            if (disabled) {
                ArrayList<String> pkgs = new ArrayList<>();
                pkgs.add(context.getPackageName());
                deviceApplicationManager.setTaskLockAppList(adminComponent, pkgs);
                deviceApplicationManager.addDisallowedRunningApp(adminComponent, List.of("com.huawei.deskclock"));
            } else {
                deviceApplicationManager.setTaskLockAppList(adminComponent, null);
                deviceApplicationManager.removeDisallowedRunningApp(adminComponent, List.of("com.huawei.deskclock"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        /*
        try {
            if (disabled) {
                deviceApplicationManager.clearSingleApp(adminComponent, context.getPackageName());
            } else {
                deviceApplicationManager.addSingleApp(adminComponent, context.getPackageName());
            }
        }catch (Exception e){
            e.printStackTrace();
        }*/
    }

    @Override
    public boolean isSingleAppControlled() {
        try {
            return restrictionManager.isBackButtonDisabled(adminComponent);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
        /*try {
            String pkg = deviceApplicationManager.getSingleApp(adminComponent);
            Log.e("mytest", "single app is: " + pkg);
            return (pkg == null || pkg.isEmpty());
        }catch (Exception e){
            e.printStackTrace();
        }
        return false;*/
    }

    @Override
    public void controlAddUser(boolean disabled) {
        settingsManager.setAddUserDisabled(adminComponent, disabled);
    }

    @Override
    public boolean isAddUserControlled() {
        return settingsManager.isAddUserDisabled(adminComponent);
    }
}
